<template>
  <view>
    <picker
        :class="disabled ? 'disabled' : ''"
        v-if="steps == 1"
        mode="selector"
        :value="idx == -1 ? 0 : idx"
        :range="options"
        :range-key="labelKeyClone"
        @change="bindChange"
        :disabled="disabled"
    >
      <view v-if="!isSlot" class="picker-cmpt outside-picker-class">
        <block v-if="labelKeyClone && options && options.length && idx >= 0 && options[idx]">
          {{ options[idx].label || noDataHint }}
        </block>
        <block v-else-if="!labelKeyClone && options && options.length && idx >= 0 && options[idx]">
          {{ options[idx] || noDataHint }}
        </block>
        <block v-else>{{ noDataHint }}</block>
      </view>
      <slot v-else />
    </picker>

    <picker
        :class="disabled ? 'disabled' : ''"
        v-if="steps > 1"
        mode="multiSelector"
        :value="idx"
        :range="options"
        :range-key="labelKeyClone"
        @tap="bindTap"
        @change="bindChange"
        :disabled="disabled"
    >
      <view v-if="!isSlot" class="picker-cmpt outside-picker-class">
        {{ multiDesc || noDataHint }}
      </view>
      <slot v-else />
    </picker>
  </view>
</template>

<script>
const helper = require('@/utils/helper/helper.js');
const dataHelper = require('@/utils/helper/data_helper.js');
const pageHelper = require('@/utils/helper/page_helper.js');
export default {
  data() {
    return {
      options: [],
      idx: 0,
      // 多选的显示文字
      multiDesc: '',

      label: '',
      sourceDataClone: [],
      labelKeyClone: '',
      itemClone: '',
      indexClone: 0
    };
  },
  externalClasses: ['outside-picker-class'],
  options: {
    addGlobalClass: true
  },
  /**
   * 一维格式： 可以通过model返回
   * 对象格式： {label:'对象A',val:'5'}, {label:'对象B',val:'12'}, {label:'对象C',val:'99'}
   * 简单形式：['形式1','形式2','形式33']
   * 字符串形式
   */

  /**
   * N维格式： 只能通过trigger返回
   * 对象格式： {label:'对象A',val:'5'}, {label:'对象B',val:'12'}, {label:'对象C',val:'99'}
   * 简单形式：['形式1','形式2','形式33']
   *
   */
  props: {
    mark: {
      type: String,
      default: ''
    },
    isSlot: {
      //是否开启slot
      type: Boolean,
      default: false
    },
    sourceData: {
      //源数组，sourceData有几维，Picker就可以有几阶 简单形式待选项,,,
      type: Array,
      default: () => []
    },
    sourceDataStr: {
      //源数组，sourceData有几维，Picker就可以有几阶 简单形式待选项,,,
      type: String,
      default: ''
    },
    // key
    labelKey: {
      type: String,
      default: ''
    },
    // 阶数
    steps: {
      type: Number,
      default: 1
    },
    noDataHint: {
      // 无数据的提示语
      type: String,
      default: '请选择'
    },
    // 选中项的下标数组 1维
    index: {
      type: Number,
      default: 0
    },
    // 选中项的下标数组 N维
    indexMulti: {
      type: Array,
      default: () => []
    },
    // 默认选中项的值数组 1维
    item: {
      type: String,
      default: ''
    },
    // 默认选中项的值数组 N维
    itemMulti: {
      type: Array,
      default: () => []
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    disabledHint: {
      //  禁用提示
      type: String,
      default: ''
    }
  },
  mounted() {
    // 处理小程序 attached 生命周期
    this.attached();
    // 处理小程序 ready 生命周期
    this.$nextTick(() => this.ready());
  },
  destroyed: function () {
    // 在组件实例被从页面节点树移除时执行
  },
  /**
   * 组件的方法列表
   */
  methods: {
    ready: function () {
      if (!this.options || this.options.length == 0) {
        this.initFun();
      }
    },

    attached: function () {},

    initFun: function () {
      let sourceData = this.sourceData;
      let labelKey = this.labelKeyClone || this.labelKey;
      let idx = this.idx;

      // 字符串形式
      if (this.steps == 1 && this.sourceDataStr && (!sourceData || sourceData.length == 0)) {
        sourceData = dataHelper.getSelectOptions(this.sourceDataStr);
        this.setData({
          sourceDataClone: sourceData
        });
      }
      if (!sourceData || sourceData.length == 0) {
        return;
      }
      if (this.steps == 1) {
        if (sourceData.length > 0 && helper.isDefined(sourceData[0]['label'])) {
          labelKey = 'label';
        }
        idx = this.index;
      } else if (this.steps > 1) {
        if (sourceData.length > 0 && helper.isDefined(sourceData[0][0]['label'])) {
          labelKey = 'label';
        }
        idx = this.indexMulti;
      }
      this.setData({
        idx,
        labelKeyClone: labelKey,
        options: sourceData
      });
      this.getMultiDescFun();
      if (this.steps == 1) {
        // 若父组件已提供默认值，按默认值选中
        if (this.item !== undefined && this.item !== null && this.item !== '') {
          this.selected(this.item);
        } else {
          // 没有默认值时，不自动选择第一项，也不触发 select 事件
          // 只设置显示索引为 -1（显示 "请选择"）
          this.setData({ 
            idx: -1, 
            indexClone: -1, 
            itemClone: '' 
          });
        }
      } else {
        this.selected(Array.isArray(this.itemMulti) ? this.itemMulti : []);
      }
    },

    getMultiDescFun: function () {
      let idx = this.idx;
      let options = this.options;
      if (!options || options.length === 0) {
        this.setData({ multiDesc: '' });
        return;
      }
      if (!Array.isArray(idx) || idx.length != options.length) {
        return;
      }
      let multiDesc = [];
      if (this.labelKeyClone) {
        for (let k = 0; k < options.length; k++) {
          multiDesc[k] = options[k][idx[k]].label;
        }
      } else {
        for (let k = 0; k < options.length; k++) {
          multiDesc[k] = options[k][idx[k]];
        }
      }
      this.setData({
        multiDesc
      });
    },

    bindTap: function (e) {
      // 点击行为
      if (this.disabled && this.disabledHint) {
        pageHelper.showModal(this.disabledHint, '提示', null, '知道了');
      }
    },

    // 触发改变
    bindChange: function (e) {
      let idx = e.detail.value;
      let val = null;
      if (this.steps == 1) {
        // 确保 options 和 idx 有效
        if (!this.options || !this.options[idx]) {
          return;
        }
        val = this.labelKeyClone ? (this.options[idx].val || this.options[idx].value) : this.options[idx];
        this.setData({
          idx: idx,
          itemClone: val,
          indexClone: idx
        });
      } else {
        val = [];
        let options = this.options;
        if (this.labelKeyClone) {
          for (let k = 0; k < options.length; k++) {
            val[k] = options[k][idx[k]].val || options[k][idx[k]].value;
          }
        } else {
          for (let k = 0; k < options.length; k++) {
            val[k] = options[k][idx[k]];
          }
        }
        this.setData({ idx });
        this.getMultiDescFun();
      }
      // 只有当用户真正选择时才触发 select 事件
      this.$emit('select', { detail: val });
    },

    // 一维数组根据val获取lable
    getLabelOneStep: function (val) {
      for (let k = 0; k < this.sourceData.length; k++) {
        if (this.sourceData[k].val == val || this.sourceData[k].value == val || 
            String(this.sourceData[k].val) === String(val) || String(this.sourceData[k].value) === String(val)) {
          return this.sourceData[k].label;
        }
      }
      return 'unknown';
    },

    // 选中值
    selected: function (val) {
      let options = this.options;
      let labelKey = this.labelKeyClone;
      if (this.steps == 1) {
        for (let k = 0; k < options.length; k++) {
          if (labelKey && (val == options[k].val || val == options[k].value || String(val) === String(options[k].val) || String(val) === String(options[k].value))) {
            this.setData({
              idx: k,
              indexClone: k
            });
            return;
          } else if (!labelKey && (val == options[k] || String(val) === String(options[k]))) {
            this.setData({
              idx: k,
              indexClone: k
            });
            return;
          }
        }
        this.setData({
          idx: -1,
          indexClone: -1
        });

        // 传入数据不匹配时，不修正父页面的值，让父页面保持原值
        // 只在内部显示为未选中状态
        // this.$emit('select', { detail: '' });
      } else if (this.steps > 1) {
        let idx = [];
        for (let k = 0; k < options.length; k++) {
          let levelTwo = options[k];
          for (let j in levelTwo) {
            if (labelKey && (val[k] == options[k][j].val || val[k] == options[k][j].value || String(val[k]) === String(options[k][j].val) || String(val[k]) === String(options[k][j].value))) {
              idx.push(j);
            } else if (!labelKey && (val[k] == options[k][j] || String(val[k]) === String(options[k][j]))) {
              idx.push(j);
            }
          }
        }
        if (idx.length != options.length) {
          idx = [];
        }
        this.setData({
          idx
        });
        this.getMultiDescFun();

        //传入数据不匹配的时候，修正父页面传入的的数组默认值 TODO
      }
    }
  },
  created: function () {},
  watch: {
    item: {
      handler: function (newVal, oldVal) {
        this.itemClone = this.clone(this.item);
        //	console.log('one observer', this.data.mark);
        if (newVal != oldVal) {
          let options = this.options;
          if (!options || options.length == 0) {
            this.initFun();
          }
          if (options && options.length > 0) {
            this.selected(newVal);
          }
        }
      },

      immediate: true
    },

    itemMulti: {
      handler: function (newVal, oldVal) {
        //	console.log('multi observer', this.data.mark);
        if (JSON.stringify(newVal) != JSON.stringify(oldVal)) {
          let options = this.options;
          if (!options || options.length == 0) {
            this.initFun();
          }
          if (options && options.length > 0) {
            this.selected(newVal);
          }
        }
      },

      immediate: true,
      deep: true
    },

    sourceData: {
      handler: function (newVal, oldVal) {
        this.sourceDataClone = newVal;
        // 外部异步传入源数据后，需要重新初始化组件内部 options/idx/labelKeyClone
        if (newVal && newVal.length) {
          this.initFun();
        }
      },

      immediate: true,
      deep: true
    },

    labelKey: {
      handler: function (newVal, oldVal) {
        // 仅当父组件显式传入 labelKey 时才覆盖自动识别结果
        if (newVal) {
          this.labelKeyClone = newVal;
        }
      },

      immediate: true
    },

    index: {
      handler: function (newVal, oldVal) {
        this.indexClone = newVal;
        // 当父传入默认下标时，直接更新 idx 以触发显示
        if (this.steps == 1 && typeof newVal === 'number') {
          this.setData({ idx: newVal });
        }
      },

      immediate: true
    }
  }
};
</script>
<style>
@import './picker_cmpt.css';
</style>
